﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

using System.Xml.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Text;
namespace UnionPay4WP
{
    public class XmlRequestBuilder
    {
        DES3 des3 = new DES3();
        UPPayRsa rsa = new UPPayRsa();
        
        //支付初始化交易——请求报文
        public string payInit()
        {
            XElement vXml=null;
           

            string sessionKey="";
            OrderClass.KeyDes3=des3.GenerateKey();
            //OrderClass.KeyDes3 = des3.GenerateKey();
            string modulusP = "108753048569348800098753919613645636933225085075547833258983694273634921524443063960133383051604104083957433830153565623666242414377093492368658981212702353786798541586182901972014826098390369194396617161757307625116206955314309688248245702061071890830881891711243088870342717281873562874779725184324932567459";
            string modulusT = "93716304585135386147007456346495207974915681551681333010606143979751660657428852845087672310448592787191681231125442581642251207627443243638648672776016343668644156640389200758863624667407953984249079575910993624091568988262627752574106503927829967495707880595781666554070793222145163225943407723575126201759";
            //sessionKey=用rsa加密后的KeyDes3
            string modulus = "";
            string eRsa = "65537";
            if (UnionPayControl.order.UseTestMode)
                modulus = modulusT;
            else
                modulus = modulusP;
            if (!rsa.RsaEncrypt(
                eRsa,
                modulus,
                OrderClass.KeyDes3,
                out sessionKey)
                )
            {

                //todo raise error?
                return "";
            }
            string temp = string.Join(",", OrderClass.KeyDes3);
            string temp2 = DES3.byteToHexStr(OrderClass.KeyDes3);

            try
            {
                vXml = new XElement("cupMobiles",
                                new XElement("cupMobile",
                                    new XAttribute("application", UnionPayControl.order.AppName),
                                    new XAttribute("version",UnionPayControl.order.Version),
                                    new XElement("transaction",
                                        new XAttribute("type", "PayInit.APReq"),
                                        new XElement("submitTime", UnionPayControl.order.SubmitTime),
                                        new XElement("order", UnionPayControl.order.OrderContent,
                                            new XAttribute("id", UnionPayControl.order.OrderId)),
                                        new XElement("transAmount", UnionPayControl.order.TransAmount.ToString().PadLeft(12, '0')),
                                        new XElement("terminal",
                                            new XAttribute("id", UnionPayControl.order.TerminalId)),
                    /*TerminalId MerchantName，MerchantId 不一定有*/
                                        new XElement("merchant",// currency
                                            new XAttribute("name", UnionPayControl.order.MerchantName),
                                            new XAttribute("id", UnionPayControl.order.MerchantId)),
                                        new XElement("mobileTerminal",
                                            new XAttribute("type", DeviceInfo.getDeviceName()),
                                            new XAttribute("os", DeviceInfo.getOSVersion()),
                                            new XAttribute("imei", DeviceInfo.getDeviceUniqueID())
                                            ),
                                        new XElement("sysProvide", UnionPayControl.order.SysProvide),//"00000002"
                                        new XElement("serviceInfo", UnionPayControl.order.ServiceInfo),
                                        new XElement("sessionKey", sessionKey)
                                        ),
                                        new XElement("senderSignature", UnionPayControl.order.Signature)
                                        ));
                if (UnionPayControl.order.TransCurrency.Length > 0)
                {
                    vXml.Element("cupMobile").Element("transaction").Element("transAmount").SetAttributeValue("currency", UnionPayControl.order.TransCurrency);//"156"
                    vXml.Element("cupMobile").Element("transaction").Element("merchant").SetAttributeValue("country", UnionPayControl.order.MerchantCountry);//"156"
                }
            }
            catch (Exception e)
            {
                
                // xmlRequest=e.StackTrace;
            }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }

        //支持银行查询交易——请求报文
        public string bankSupportEnquiry()
        {
            XElement vXml = null;

            try
            {

                vXml = new XElement("cupMobiles",
                               new XElement("cupMobile",
                                   new XAttribute("application", "UPNoCard"),
                                   new XAttribute("version", "1.01"),
                                   new XElement("transaction",
                                       new XAttribute("type", "BankSupportEnquiry.APReq"),
                                       new XElement("sessionID", UnionPayControl.order.SessionID)
                                      
                                       )));
            }
            catch (Exception e)
            {

                // xmlRequest=e.StackTrace;
            }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }

        //短信验证码生成交易
        public string sMSGenerate(string phoneNum)
        {
            XElement vXml = null;

            try
            {

                vXml = new XElement("cupMobiles",
                               new XElement("cupMobile",
                                   new XAttribute("application", "UPNoCard"),
                                   new XAttribute("version", "1.01"),
                                   new XElement("transaction",
                                       new XAttribute("type", "SMSGenerate.APReq"),
                                       new XElement("sessionID", UnionPayControl.order.SessionID),
                                       new XElement("phoneNum", des3.EncryptMobilePhoneNum(phoneNum, OrderClass.KeyDes3))//d1c54c4af23f4b70e6287a67ffb3e133
                                       )));
            }
            catch (Exception e)
            {
                // xmlRequest=e.StackTrace;
            }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }

        //卡信息查询+卡交易信息查询+短信验证码验证
        public string cardInfoEnquiry(string accountNumber1,string phoneNum,string checkCode)
        {
            
            // for test
            XElement vXml = null;

            try
            {
                string key = "",value="";
                if ("" != Setting.accountUniqueID)
                {
                    key="accountUniqueID";
                    //value = Setting.accountUniqueID; 
                    value = des3.Encrypt40(Setting.accountUniqueID, OrderClass.KeyDes3);
                }
                else
                {
                    key = "accountNumber1";
                    value = des3.EncryptAccountNum(accountNumber1, OrderClass.KeyDes3);
                }

                vXml = new XElement("cupMobiles",
                               new XElement("cupMobile",
                                   new XAttribute("application", "UPNoCard"),
                                   new XAttribute("version", "1.01"),
                                   new XElement("transaction",
                                       new XAttribute("type", "CardInfoEnquiry.APReq"),
                                       new XElement("accountNumber1",des3.EncryptAccountNum(accountNumber1, OrderClass.KeyDes3)),
                                       new XElement("sessionID", UnionPayControl.order.SessionID)
                                       )),
                                   new XElement("cupMobile",
                                   new XAttribute("application", "UPNoCard"),
                                   new XAttribute("version", "1.01"),
                                   new XElement("transaction",
                                       new XAttribute("type", "CardTransInfoEnquiry.APReq"),
                                       new XElement(key, value),//*标记一下*/
                                       new XElement("sessionID", UnionPayControl.order.SessionID)
                                       )));
               
                int limit = Convert.ToInt32(OrderClass.LimitedAmount);
                if (limit <= UnionPayControl.order.TransAmount)//加验证码验证环节
                {
                    vXml.Add(new XElement("cupMobile",
                                   new XAttribute("application", "UPNoCard"),
                                   new XAttribute("version", "1.01"),
                                   new XElement("transaction",
                                       new XAttribute("type", "SMSVerification.APReq"),
                                       new XElement("sessionID", UnionPayControl.order.SessionID),
                                       new XElement("phoneNum", des3.EncryptMobilePhoneNum(phoneNum, OrderClass.KeyDes3)),
                                       new XElement("msgAuthCode", checkCode)
                                       )));
                }
            }
            catch (Exception e)
            {
                // xmlRequest=e.StackTrace;
            }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }
/*
C.4.2.1 卡交易查询——请求报文
<?xml version="1.0" encoding="UTF-8"?>
<cupMobiles>
	<cupMobile application="UPNoCard" version="1.01">
		<transaction type="CardTransInfoEnquiry.APReq">
			<accountUniqueID>aedffff8f22a876614472726b0c464157049d340ce701c18cac1a35224f3c2be2097d1ec9b7e7313</accountUniqueID>
			<sessionID>0d0dd40afc37458c820e9bbe3a79eb80</sessionID>
		</transaction>
	</cupMobile>
</cupMobiles>
        */

        //交易
        public string purchase(bool flag=false)
        {
            XElement vXml = null;

            try
            {
                string key = "", value = "";
                if (""!=Setting.accountUniqueID)
                {
                    key = "accountUniqueID";
                    value = des3.Encrypt40(Setting.accountUniqueID, OrderClass.KeyDes3);
                }
                else
                {
                    key = "accountNumber1";
                    value = des3.EncryptAccountNum(ServerResponseVars.account, OrderClass.KeyDes3);//这个地方和上面函数不一样，上面的函数是传值的，这个用了公共变量
                }
                if (Setting.cardType == "CreditCard")
                {
                    vXml = new XElement("cupMobiles",
                                   new XElement("cupMobile",
                                       new XAttribute("application", "UPNoCard"),
                                       new XAttribute("version", "1.01"),
                                       new XElement("transaction",
                                           new XAttribute("type", "Purchase.APReq"),
                                           new XElement(key, value),
                                           new XElement("sessionID", UnionPayControl.order.SessionID),
                                           new XElement("CVN2", des3.EncryptCheckCode(OrderClass.pin, OrderClass.KeyDes3)),
                                           new XElement("expireDate", des3.EncryptCheckCode(/*OrderClass.date*/(Setting.limitMonth+Setting.limitYear), OrderClass.KeyDes3))/**/
                                           )));
                    if ("accountNumber1" == key)
                    {
                        vXml.Element("cupMobile").Element("transaction").Add(new XElement("phoneNum", des3.EncryptMobilePhoneNum(/*ServerResponseVars.phoneNum*/Setting.phoneNum, OrderClass.KeyDes3)));
                    }
                }
                else
                {
                   vXml = new XElement("cupMobiles",
                                   new XElement("cupMobile",
                                       new XAttribute("application", "UPNoCard"),
                                       new XAttribute("version", "1.01"),
                                       new XElement("transaction",
                                           new XAttribute("type", "Purchase.APReq"),
                                           new XElement(key, value),
                                           new XElement("sessionID", UnionPayControl.order.SessionID),
                                           new XElement("pin", des3.EncryptCheckCode(OrderClass.pin, OrderClass.KeyDes3))
                                           )));
                    if ("accountNumber1" == key)
                    {
                        vXml.Element("cupMobile").Element("transaction").Add(new XElement("phoneNum", des3.EncryptMobilePhoneNum(/*ServerResponseVars.phoneNum*/Setting.phoneNum, OrderClass.KeyDes3)));
                    }
                }
            }
            catch (Exception e)
            {

                // xmlRequest=e.StackTrace;
            }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }

        //认证交易
        /*
        public string authenticate(XElement xml)
        {
            XElement vXml = null;
            string sessionKey="";
            OrderClass.KeyDes3=des3.GenerateKey();
            //sessionKey=用rsa加密后的KeyDes3
            if (!rsa.RsaEncrypt(
                "",
                "",
                OrderClass.KeyDes3,
                out sessionKey)
                )
            {

                //todo raise error?
                return "";
            }
            try
            {
                vXml = new XElement("cupMobiles",
                    new XElement("cupMobile",
                        new XAttribute("application", "UPNoCard"),
                        new XAttribute("version", "1.01"),
                        new XElement("transaction",
                            new XAttribute("type", "Authenticate.APReq"),
                            new XElement("submitTime", UnionPayControl.order.SubmitTime),
                            new XElement("order", UnionPayControl.order.OrderContent,
                                new XAttribute("id", UnionPayControl.order.OrderId)),
                            new XElement("contentProvide", UnionPayControl.order.ContentProvide),
                            new XElement("sysProvide", UnionPayControl.order.SysProvide),
                            new XElement("sessionKey", sessionKey)),
                    new XElement("senderSignature", "")));//是啥呀？
            }
            catch { }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }
       
        */
        //查询余额
        public string balanceEnquiry(string accountNumber1,string phoneNum)
        {
            XElement vXml = null;
            try
            {
                vXml=new XElement("cupMobiles",
                    new XElement("cupMobile",
                        new XAttribute("application","UPNoCard"),
                        new XAttribute("version","1.01"),
                        new XElement("transaction",
                            new XAttribute("type","BalanceEnquiry.APReq"),
                            new XElement("accountNumber1", des3.EncryptAccountNum(accountNumber1, OrderClass.KeyDes3)),
                            new XElement("phoneNum",des3.EncryptMobilePhoneNum(phoneNum,OrderClass.KeyDes3)),
                            new XElement("sessionID",UnionPayControl.order.SessionID)
                            )));
                if(Setting.cardType == "CreditCard")
                {
                    vXml.Element("cupMobile").Element("transaction").Add(new XElement("CVN2", des3.EncryptCheckCode(OrderClass.pin, OrderClass.KeyDes3)));
                    vXml.Element("cupMobile").Element("transaction").Add(new XElement("expireDate", des3.EncryptCheckCode(Setting.limitYear+Setting.limitMonth, OrderClass.KeyDes3)));
                }
                else
                {
                    vXml.Element("cupMobile").Element("transaction").Add(new XElement("pin", des3.EncryptCheckCode(OrderClass.pin, OrderClass.KeyDes3)));
                }
            }
            catch { }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }
        //版本验证
        public string versionValidation(XElement xml)
        {
          
            XElement vXml = null;
            try
            {
                vXml = new XElement("cupMobiles",
                               new XElement("cupMobile",
                                   new XAttribute("application", "UPNoCard"),
                                   new XAttribute("version", "1.01"),
                                   new XElement("transaction",
                                       new XAttribute("type", "VersionValidation.APReq"),
                                       new XElement("mobileTerminal",
                                           new XAttribute("type", DeviceInfo.getDeviceName()),
                                           new XAttribute("os", DeviceInfo.getOSVersion()),
                                           new XAttribute("imei", DeviceInfo.getDeviceUniqueID())))));
            }
            catch { }
            string xmlRequest = @"<?xml version=""1.0"" encoding=""UTF-8""?>
" + vXml.ToString();
            return xmlRequest;
        }

        private string StringWithDeclaration(XDocument doc)
        {
            if (doc == null)
            {
                throw new ArgumentNullException("doc");
            }
            StringBuilder builder = new StringBuilder();
            using (TextWriter writer = new StringWriter(builder))
            {
                doc.Save(writer);
            }
            return builder.ToString();
        }

    }

}
